﻿using Google.Protobuf.WellKnownTypes;
using HirelSeriesH.Global;
using HirelSeriesH.Tools;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Reflection;
using System.Text;
using System.Timers;

namespace HirelSeriesH.Entity
{
    /// <summary>
    /// 电源实体类
    /// </summary>
    public class Power
    {
        private string iD;
        /// <summary>
        /// 电源名称
        /// </summary>
        private string powerName;
        /// <summary>
        /// 电压量程
        /// </summary>
        private decimal maxVoltage;
        /// <summary>
        ///电流量程
        /// </summary>
        private decimal maxCurrent;
        /// <summary>
        /// 设定的目标电压
        /// </summary>
        private decimal voltage;

        private decimal voltageFirst;

        /// <summary>
        /// 升降压过程中的当前电压
        /// </summary>
        private decimal voltageCurrent;
        /// <summary>
        /// 升压步长
        /// </summary>
        private decimal upStep;
        /// <summary>
        /// 升压间隔
        /// </summary>
        private decimal upInterval;
        /// <summary>
        /// 降压步长
        /// </summary>
        private decimal downStep;
        /// <summary>
        /// 降压间隔
        /// </summary>
        private decimal downInterval;
        /// <summary>
        /// 监控周期
        /// </summary>
        private decimal checkInterval;
        /// <summary>
        /// 电源的实时电压
        /// </summary>
        private decimal realVoltage = 0;
        /// <summary>
        /// 电源的实时电流
        /// </summary>
        private decimal realCurrent = 0;
        /// <summary>
        /// 定时查询电源输出电压和电流
        /// </summary>
        private Timer timerForLowPowerRealVC = new Timer();
        /// <summary>
        /// 保护电阻
        /// </summary>
        private decimal bHDZ;
        /// <summary>
        /// 是否已开启
        /// </summary>
        private bool isOpen;
        /// <summary>
        /// 是否处于升压或降压状态
        /// </summary>
        private bool isUpDown = false;
        /// <summary>
        /// 升压计时器
        /// </summary>
        private Timer timerUp = new Timer();
        /// <summary>
        /// 降压压计时器
        /// </summary>
        private Timer timerDown = new Timer();

        private int index;

        int tempTime = 0;

        private bool stopUp = false;

        //子窗口声明定义委托 refresh()
        public delegate void RefreshDelegate();
        public event RefreshDelegate refreshButton;

        private List<UIDoubleUpDown> numList;

        private UIButton buttonAction;

        private System.Windows.Forms.Label label;

        private decimal voltageValue;

        private decimal upStepVal;

        private Channel channel;

        private bool listening = false;//是否没有执行完invoke相关操作  

        private bool closing = false;//是否正在关闭串口，执行Application.DoEvents，并阻止再次invoke  

        /// <summary>
        /// 是否通信异常
        /// </summary>
        private bool isCommunityError = false;

        private bool isTest = false;

        public string AC = "None";

        private int highErrorCount = 0;
        private decimal fdVolt = 10;

        private decimal onTime;
        private decimal offTime;
        private decimal onTimeSec;
        private decimal offTimeSec;
        private decimal onTimeWorkedSec;
        private decimal offTimeWorkedSec;

        public string State = "off";

        //public Timer TimerForWork;
        public Timer TimerForReadData;
        public bool NeedEnd = false;

        //private readonly object locker = new object();

        public Power(int index)
        {
            Index = index;

            /*timerUp.Elapsed += new ElapsedEventHandler(TimerUpTaskLow);
            //设置是执行一次（false）还是一直执行(true)
            timerUp.AutoReset = true;
            //是否执行System.Timers.Timer.Elapsed事件
            timerUp.Enabled = false;

            timerDown.Elapsed += new ElapsedEventHandler(TimerDownTaskLow);
            //设置是执行一次（false）还是一直执行(true)
            timerDown.AutoReset = true;
            //是否执行System.Timers.Timer.Elapsed事件
            timerDown.Enabled = false;*/


            //TimerForWork = new Timer();
            //TimerForWork.AutoReset = true;
            //TimerForWork.Enabled = false;
            //TimerForWork.Elapsed += new ElapsedEventHandler(TimerForWork_Tick);
            //TimerForWork.Interval = 1000;

            TimerForReadData = new System.Timers.Timer();
            TimerForReadData.AutoReset = true;
            TimerForReadData.Enabled = false;
            TimerForReadData.Elapsed += new ElapsedEventHandler(TimerForReadData_Tick);
            TimerForReadData.Interval = 1000;

            //查询电源电压电流
            TimerForLowPowerRealVC.AutoReset = true;
            TimerForLowPowerRealVC.Enabled = false;
            TimerForLowPowerRealVC.Elapsed += new ElapsedEventHandler(timerForLowPowerRealVC_Tick);
            TimerForLowPowerRealVC.Interval = 2000;
        }

        public string ID { get => iD; set => iD = value; }
        public string PowerName { get => powerName; set => powerName = value; }
        public decimal Voltage { get => voltage; set => voltage = value; }
        public decimal UpStep { get => upStep; set => upStep = value; }
        public decimal UpInterval { get => upInterval; set => upInterval = value; }
        public decimal DownStep { get => downStep; set => downStep = value; }
        public decimal DownInterval { get => downInterval; set => downInterval = value; }
        public decimal CheckInterval { get => checkInterval; set => checkInterval = value; }
        public decimal BHDZ { get => bHDZ; set => bHDZ = value; }
        public decimal MaxVoltage { get => maxVoltage; set => maxVoltage = value; }
        public decimal MaxCurrent { get => maxCurrent; set => maxCurrent = value; }
        public bool IsOpen { get => isOpen; set => isOpen = value; }
        public decimal VoltageCurrent { get => voltageCurrent; set => voltageCurrent = value; }
        public Timer TimerUp { get => timerUp; set => timerUp = value; }
        public Timer TimerDown { get => timerDown; set => timerDown = value; }
        public bool IsUpDown { get => isUpDown; set => isUpDown = value; }
        public int TempTime { get => tempTime; set => tempTime = value; }
        public decimal RealVoltage { get => realVoltage; set => realVoltage = value; }
        public decimal RealCurrent { get => realCurrent; set => realCurrent = value; }
        public Timer TimerForLowPowerRealVC { get => timerForLowPowerRealVC; set => timerForLowPowerRealVC = value; }
        public System.Windows.Forms.Label Label { get => label; set => label = value; }
        public decimal VoltageValue { get => voltageValue; set => voltageValue = value; }
        public decimal UpStepVal { get => upStepVal; set => upStepVal = value; }
        internal Channel Channel { get => channel; set => channel = value; }
        public bool Listening { get => listening; set => listening = value; }
        public bool Closing { get => closing; set => closing = value; }
        public int Index { get => index; set => index = value; }
        public bool IsCommunityError { get => isCommunityError; set => isCommunityError = value; }
        public decimal VoltageFirst { get => voltageFirst; set => voltageFirst = value; }
        public bool StopUp { get => stopUp; set => stopUp = value; }
        public bool IsTest { get => isTest; set => isTest = value; }
        public UIButton ButtonAction { get => buttonAction; set => buttonAction = value; }
        public List<UIDoubleUpDown> NumList { get => numList; set => numList = value; }
        public decimal FdVolt { get => fdVolt; set => fdVolt = value; }
        public decimal OnTime { get => onTime; set => onTime = value; }
        public decimal OffTime { get => offTime; set => offTime = value; }
        public decimal OnTimeSec { get => onTimeSec; set => onTimeSec = value; }
        public decimal OffTimeSec { get => offTimeSec; set => offTimeSec = value; }
        public decimal OnTimeWorkedSec { get => onTimeWorkedSec; set => onTimeWorkedSec = value; }
        public decimal OffTimeWorkedSec { get => offTimeWorkedSec; set => offTimeWorkedSec = value; }

        public void open()
        {
            System.Threading.Thread.Sleep(50);
            Global.Global.LowPowerPortList[Index].Write("OUT 1" + "\r\n");
            System.Threading.Thread.Sleep(50);
        }

        public void close()
        {
            System.Threading.Thread.Sleep(50);
            Global.Global.LowPowerPortList[Index].Write("OUT 0" + "\r\n");
            System.Threading.Thread.Sleep(50);
        }

        public void setMaxCurrent()
        {
            System.Threading.Thread.Sleep(50);
            Global.Global.LowPowerPortList[Index].Write("PC " + MaxCurrent + "\r\n");
            System.Threading.Thread.Sleep(50);
        }

        public void setVolt(decimal voltage)
        {
            System.Threading.Thread.Sleep(30);
            Global.Global.LowPowerPortList[Index].Write("PV " + voltage + "\r\n");
            System.Threading.Thread.Sleep(30);
            Global.Global.LowPowerPortList[Index].Write("PV " + voltage + "\r\n");
            System.Threading.Thread.Sleep(30);
            Global.Global.LowPowerPortList[Index].Write("PV " + voltage + "\r\n");
        }

        //public void OnPower()
        //{
        //    lock(locker)
        //    {
        //        if (IsOpen)
        //        {
        //            return;
        //        }
        //        setMaxCurrent();
        //        System.Threading.Thread.Sleep(50);
        //        open();
        //        System.Threading.Thread.Sleep(50);
        //        setVolt(Voltage);

        //        onTimeSec = onTime * 60;
        //        offTimeSec = offTime * 60;

        //        onTimeWorkedSec = 0;
        //        offTimeWorkedSec = 0;

        //        IsOpen = true;
        //        State = "on";

        //        TimerForWork.Start();
        //    }
        //}

        //public void OffPower()
        //{
        //    lock (locker)
        //    {
        //        if (!IsOpen)
        //        {
        //            return;
        //        }
        //        TimerForWork.Stop();
        //        System.Threading.Thread.Sleep(100);
        //        close();
        //        System.Threading.Thread.Sleep(50);
        //        setVolt(0);
        //        IsOpen = false;

        //        //清除面显示的电源状态以及状态倒计时(秒)
        //        /*if ((Global.Global.CurrentChannel != null) && (Global.Global.CurrentChannel.PowerGroup != null) && (Global.Global.CurrentChannel.PowerGroup.Index == Index))
        //        {
        //            invokeData[0] = "";
        //            invokeData[1] = "";
        //            Global.Global.PgState.BeginInvoke(new VoltageVCDelegate(VoltageVCDelegateMethod), invokeData);
        //        }*/
        //    }
        //}

        //private void TimerForWork_Tick(object sender, EventArgs e)
        //{
        //    if (State == "on")
        //    {
        //        onTimeWorkedSec++;

        //        if (onTimeWorkedSec == onTimeSec)
        //        {
        //            onTimeWorkedSec = 0;
        //            State = "off";
        //            setVolt(0);//撤除电压
        //        }
        //        else
        //        {
        //            int cIndex = 0;
        //            读取数据 Global.Global.DataIRList[i]
        //            for (int i = Index; i < Global.Global.DataIRList.Count; i = i + Global.Global.ChannelList[0].Positions.Count)
        //            {
        //                decimal IR = Global.Global.DataIRList[i];
        //                decimal outPutVolt = RealVoltage;
        //                decimal VR = outPutVolt;
        //                if (VR < 0)
        //                {
        //                    VR = 0;
        //                }
        //                Channel channel = Global.Global.ChannelList[cIndex];
        //                if (channel.State == "running" && (onTimeWorkedSec > 3))
        //                {
        //                    if (channel.TestParameter.PowerUseList[Index])
        //                    {
        //                        channel.Positions[Index].IValue = IR;
        //                        channel.Positions[Index].UValue = VR;
        //                    }
        //                    else
        //                    {
        //                        channel.Positions[Index].IValue = 0;
        //                        channel.Positions[Index].UValue = 0;
        //                    }
        //                }
        //                cIndex++;
        //            }

        //        }
        //    }
        //    else
        //    {
        //        offTimeWorkedSec++;

        //        if (offTimeWorkedSec == offTimeSec)
        //        {
        //            offTimeWorkedSec = 0;
        //            State = "on";
        //            setVolt(Voltage);//施加电压
        //        }
        //        else
        //        {
        //            int cIndex = 0;
        //            decimal IR = 0;
        //            decimal VR = 0;
        //            读取数据 Global.Global.DataIRList[i]
        //            for (int i = Index; i < Global.Global.DataIRList.Count; i = i + Global.Global.ChannelList[0].Positions.Count)
        //            {
        //                Channel channel = Global.Global.ChannelList[cIndex];
        //                channel.Positions[Index].IValue = IR;
        //                channel.Positions[Index].UValue = VR;
        //                cIndex++;
        //            }
        //        }

        //    }

        //}

        private void TimerForReadData_Tick(object sender, EventArgs e)
        {
            int start, end, cIndexStart, idx;
            if (Index < 4)
            {
                cIndexStart = 0;
                idx = Index;
                start = Index;
                end = Global.Global.DataIRList.Count - 16;
            }
            else
            {
                cIndexStart = 4;
                idx = Index - 4;
                start = idx + 16;
                end = Global.Global.DataIRList.Count;
            }
            /*if (Index == 4)
            {
                Debug.WriteLine("start:" + start + "  end:" + end + "  cIndexStart:" + cIndexStart + "  idx:" + idx);
            }*/

            if (IsOpen)
            {
                //读取数据 
                for (int i = start; i < end; i = i + Global.Global.ChannelList[0].Positions.Count)
                {
                    decimal IR = Global.Global.DataIRList[i];
                    decimal VR = Global.Global.DataVoltList[i];
                    /*if (VR < 0)
                    { 
                        VR = 0;
                    }*/
                    Channel channel = Global.Global.ChannelList[cIndexStart];
                    if (channel.State == "running")
                    {
                        if (channel.Positions[idx].IsUse)
                        {
                            channel.Positions[idx].IValue = IR;
                            channel.Positions[idx].UValue = VR;
                        }
                        else
                        {
                            channel.Positions[idx].IValue = 0;
                            channel.Positions[idx].UValue = 0;
                        }
                    }
                    cIndexStart++;
                }
            }
            else
            {
                decimal IR = 0;
                decimal VR = 0;
                //读取数据 Global.Global.DataIRList[i]
                for (int i = start; i < end; i = i + Global.Global.ChannelList[0].Positions.Count)
                {
                    Channel channel = Global.Global.ChannelList[cIndexStart];
                    channel.Positions[idx].IValue = IR;
                    channel.Positions[idx].UValue = VR;
                    cIndexStart++;
                }
            }
        }
        /// <summary>
        /// 查询电源实时输出值（电压、电流）.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerForLowPowerRealVC_Tick(object sender, EventArgs e)
        {

            try
            {
                if (Global.Global.LowPowerPortList[Index] == null || !Global.Global.LowPowerPortList[Index].IsOpen)
                {
                    IsCommunityError = true;
                    return;
                }
                else
                {
                    IsCommunityError = false;
                }

                string strVolt = "";
                Global.Global.LowPowerPortList[Index].Write("ADR 1" + "\r\n");
                System.Threading.Thread.Sleep(50);
                Global.Global.LowPowerPortList[Index].Write("RMT 2" + "\r\n");
                System.Threading.Thread.Sleep(50);
                Global.Global.LowPowerPortList[Index].DiscardInBuffer();
                //查询实时电压
                Global.Global.LowPowerPortList[Index].Write("MV?" + "\r\n");

                for (int i = 0; i < 8; i++)
                {
                    System.Threading.Thread.Sleep(50);
                    try
                    {
                        strVolt += Global.Global.LowPowerPortList[Index].ReadExisting();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(PowerName + "，电压返回通信异常:" + ex.StackTrace);
                        return;
                    }
                    if (strVolt.IndexOf("\n") >= 0) break;
                }
                strVolt = strVolt.Replace("\n", "");

                if (strVolt == null || strVolt == "")
                {
                    IsCommunityError = true;
                    return;
                }
                else
                {
                    IsCommunityError = false;
                }

                if (strVolt.Contains("?"))
                {
                    return;
                }
                if (strVolt.IndexOf("e") != -1)
                {
                    if (!IsOpen && !IsUpDown)
                    {
                        RealVoltage = 0;
                    }
                }
                else
                {
                    try 
                    {
                        strVolt = strVolt.Replace("\r\n", "");
                        strVolt = strVolt.Replace("OK","");
                        decimal TempVoltage = decimal.Parse(strVolt);

                        if (TempVoltage <= 0)
                        {
                            if (!IsOpen && !IsUpDown)
                            {
                                RealVoltage = 0;
                            }
                        }
                        else
                        {
                            RealVoltage = Math.Round(TempVoltage, 3);
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(PowerName + ",电压返回值异常:" + strVolt);
                        return;
                    }
                }

                /*if (IsOpen && !IsUpDown)
                {
                    if ((RealVoltage > (Voltage + FdVolt)) || (RealVoltage < (Voltage - FdVolt)))
                    {
                        highErrorCount++;
                    }
                    else
                    {
                        highErrorCount = 0;
                    }
                    if (highErrorCount >= 5)
                    {
                        setVolt(0);
                        close();
                        IsOpen = false;
                        IsUpDown = false;
                        highErrorCount = 0;
                        writeErr(Voltage, RealVoltage);
                    }
                }
                else
                {
                    highErrorCount = 0;
                }*/

                if (!Global.Global.LowPowerPortList[Index].IsOpen)
                {
                    return;
                }
                string strCurr = "";

                Global.Global.LowPowerPortList[Index].DiscardInBuffer();
                //查询实时电流
                Global.Global.LowPowerPortList[Index].Write("MC?" + "\r\n");

                for (int i = 0; i < 8; i++)
                {
                    System.Threading.Thread.Sleep(50);
                    try
                    {
                        strCurr += Global.Global.LowPowerPortList[Index].ReadExisting();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(PowerName + "电流返回通信异常:" + ex.StackTrace);
                        return;
                    }
                    if (strCurr.IndexOf("\n") >= 0) break;
                }

                strCurr = strCurr.Replace("\n", "");
                if (strCurr.Contains("?"))
                {
                    return;
                }
                if (strCurr.IndexOf("e") != -1)
                {
                    RealCurrent = 0;
                }
                else
                {
                    try
                    {
                        strCurr = strCurr.Replace("\r\n", "");
                        strCurr = strCurr.Replace("OK", "");
                        RealCurrent = Math.Round(decimal.Parse(strCurr), 2);

                        if (RealCurrent < 0)
                        {
                            RealCurrent = 0;
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(PowerName + "电流返回值异常:" + strCurr);
                        return;
                    }

                }
            }
            catch (Exception exx)
            {
                Debug.WriteLine(exx.StackTrace);
                return;
            }
        }

        private void writeErr(decimal voltObj, decimal voltReal)
        {
            string fileName = "\\" + PowerName + ".csv";
            string filePath = "D:\\电压异常报警记录";

            bool isfirst = false;
            FileStream fileStream;
            if (!Directory.Exists(filePath))
            {
                //创建文本文件夹
                Directory.CreateDirectory(filePath);
            }
            if (!File.Exists(filePath + fileName))
            {
                //创建写入文本文件
                fileStream = new FileStream(filePath + fileName, FileMode.Create);
                fileStream.Close();
                isfirst = true;
            }

            if (isfirst)
            {
                string firstRow = "日期\t时间\t设定电压\t实际输出电压\t" + "\r\n";
                fileStream = new FileStream(filePath + fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                StreamWriter swrFirstRow = new StreamWriter(fileStream, Encoding.Unicode);
                swrFirstRow.Write(firstRow);
                swrFirstRow.Flush();
                fileStream.Flush();
                swrFirstRow.Close();
            }
            string date = DateTime.Now.ToString("yyyy-MM-dd");
            string time = DateTime.Now.ToLongTimeString();
            string titleStr = date + "\t" + time + "\t" + voltObj + "\t" + voltReal + "\t" + "\r\n";

            fileStream = new FileStream(filePath + fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
            StreamWriter swr = new StreamWriter(fileStream, Encoding.Unicode);
            swr.Write(titleStr);
            swr.Flush();
            fileStream.Flush();
            swr.Close();

        }

    }
}
